package cn.edu.scau.cmi.ema.util;


import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 类的属性复制工具类， 这个类好像没有用上
 *
 * @author wangfan
 * @date 2017-6-3 下午5:08:15
 */
public class CmiAttributeUtil {
	/**
	 * 复制父类的属性到子类
	 *
	 * @param father
	 * @param child
	 */
	public static <F, C extends F> void copy(F father, C child) {
		Class<?> fatherClass = father.getClass();
		Field ff[] = fatherClass.getDeclaredFields();
		for (int i = 0; i < ff.length; i++) {
			Field f = ff[i]; // 取出每一个属性
			try {
				// 通过父类get方法取出属性值
				Method mf = fatherClass.getMethod("get" + upperHeadChar(f.getName()));
				Object obj = mf.invoke(father);
				// 获得set方法的名字让子类执行
				Method mc = fatherClass.getMethod("set" + upperHeadChar(f.getName()), f.getType());
				mc.invoke(child, obj);
			} catch (NoSuchMethodException e) {
				// System.out.println("字段"+f.getName()+"没有get或set方法");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 *
	 * @param <F>
	 * @param <C>
	 * @param father
	 * @param child  复制子类的属性到父类 弥补子类强制转换为父类，实际上还是子类的缺点：
	 *               debug过程发现child强制转换为father后，father依然具有child的各种属性值，只是不能通过get方法获得，也就是说实际上father还是child
	 *               reverseCopy方法则可以避免这种情况发生
	 */
	public static <F, C extends F> void reverseCopy(F father, C child) {
		// 把子类的属性值复制到父类中对应属性值，只需要循环父类的Field就可以了
		Class<?> fatherClass = father.getClass();
		Field ff[] = fatherClass.getDeclaredFields();
		for (int i = 0; i < ff.length; i++) {
			// 取出父类每一个属性
			Field f = ff[i];
			if (!f.getName().equalsIgnoreCase("serialVersionUID")) {
				try {
					// 通过父类get方法取出属性值
					Method mc = fatherClass.getMethod("get" + upperHeadChar(f.getName()));
					Object obj = mc.invoke(child);
					// 获得set方法的名字让父类执行
					Method mf = fatherClass.getMethod("set" + upperHeadChar(f.getName()), f.getType());
					mf.invoke(father, obj);

				} catch (NoSuchMethodException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 把父类克隆为子类
	 *
	 * @param father
	 * @param child
	 */
	public static <F, C extends F> C clone(F father, Class<C> clazz) {
		C child = null;
		try {
			child = clazz.newInstance();
			copy(father, child);
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return child;
	}

	/**
	 * 首字母大写
	 *
	 * @param in
	 * @return
	 */
	private static String upperHeadChar(String in) {
		String head = in.substring(0, 1);
		String out = head.toUpperCase() + in.substring(1, in.length());
		return out;
	}
}

